﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using Tauren.Form.DLL.Form_TableInfoDLL;
using Tauren.Form.DLL.Resouces;
using Tauren.Form.Entity.Config;
using Tauren.Form.Entity.Const;
using Tauren.Form.Entity.Enum;
using Tauren.Form.Entity.Global;
using Tauren.Form.Entity.Input;
using Tauren.Form.Entity.Model;
using Tauren.Form.Entity.Output;
using Tauren.Form.Infrastructure.Common;
using Tauren.Form.Infrastructure.Globals;

namespace Tauren.Form.Service.Form_TableInfoBLL
{
    public class Form_TableInfoService : Form_TableImImpService
    {
        private IForm_TableInfoBusiness business;

        public override double VersionName => 1.0;
        #region public
        public Form_TableInfoService(IForm_TableInfoBusiness _business, IConnectionBLLBase connectionBLL, IMenuResourcesBusiness resourcesBusiness) : base(_business, connectionBLL, resourcesBusiness)
        {
            business = _business;
            this.ResourcesInfo = this.GetResources(GlobalConst.RESOURCES_FLAG_MODULE_FORM_TABLEINFO_KEY);
            this.JudePrmission(GlobalConst.RESOURCES_FLAG_MODULE_FORM_TABLEINFO_KEY.ToLower());
        }
        /// <summary>
        /// 加载表单字段
        /// </summary>
        /// <param name="PageType"></param>
        /// <returns></returns>
        public override IResponseMessage Config(string PageType)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            List<OutPutConfig> Fields = new List<OutPutConfig>();

            OutPutConfig config = new OutPutConfig();
            config.Label = this.CommonText("fieldtableinfo");
            config.FieldKey = "tables";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_FORM_TABLEINFO_KEY.ToLower();
            config.ControlType = ControlType.tableinfo;
            config.SelectType = SelectType.radio;
            config.Show = true;
            config.Editor = PageType != "view" && PageType != "edit";
            config.Required = PageType != "view" && PageType != "edit";
            config.Results = new List<Options>() { new Options() { Label = "tableCode", Value = "tableCode" },
                new Options() { Label = "flowTableCode", Value = "flowTableCode" }, new Options() { Label = "pkTable", Value = "tableCode" } };
            config.paramters.Add(new Entity.Output.Options() { Label = "isPrimary", Value = 1, FixedValeu = true });
            Dictionary<object, object> rule = new Dictionary<object, object>();
            if (PageType != "view")
            {
                #region 添加验证规则

                rule.Add("required", true);
                rule.Add("message", this.CommonText("fieldsrequired"));
                rule.Add("trigger", "blur");
                config.Rules.Add(rule);
            }
            BuliedTableConfig(config.Tables, PageType, new List<FromTableHeader>() { new FromTableHeader { FieldKey = "tableCode", Primary = true }, new FromTableHeader { FieldKey = "tableName" } }, config.Operations);
            Fields.Add(config);
            #endregion           
            config = new OutPutConfig();
            config.Label = this.CommonText("fieldchildtables");
            config.FieldKey = "childTables";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_FORM_TABLEINFO_KEY.ToLower();
            config.ControlType = ControlType.tableinfo;
            config.SelectType = SelectType.multi;
            config.Show = true;
            config.Editor = PageType != "view";
            config.Required = PageType != "view";
            config.paramters.Add(new Entity.Output.Options() { Label = "pkTable" });
            rule = new Dictionary<object, object>();
            BuliedTableConfig(config.Tables, PageType, new List<FromTableHeader>() { new FromTableHeader { FieldKey = "tableCode", Primary = true }, new FromTableHeader { FieldKey = "tableName" } }, config.Operations);
            Fields.Add(config);
            return Fields.Succeed();
        }

        public override IResponseMessage Pages(QueryModel queryModel)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));

            ///获取基础数据库中表信息
            List<TableInfo> tableInfos = business.GetAll<TableInfo>();
            TableListModel<PageForm_TableInfoTable> tableListModel = new TableListModel<PageForm_TableInfoTable>();
            List<TableListHeaderModele> Headers = new List<TableListHeaderModele>();
            Headers.Add(new TableListHeaderModele() { Key = "rowNo", Name = CommonText("rowNo"), Width = 50, Align = "center", Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "autoId", Name = CommonText("autoid"), Width = 70, Hide = true, Type = "primary_key", Align = "center", SorTable = SortType.custom.ToString(), Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "tableCode", Name = CommonText("thcode"), Width = 160, Align = "left", Type = "primary_key", SorTable = SortType.custom.ToString(), Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "cnName", Name = CommonText("thcnname"), Width = 220, Align = "left", IsOperation = true, Fixed = true, });
            Headers.Add(new TableListHeaderModele() { Key = "enName", Name = CommonText("thenname"), Width = 220, Align = "left", Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "foreignKey", Name = CommonText("fieldcode"), Width = 160, Align = "left", SorTable = SortType.custom.ToString() });
            Headers.Add(new TableListHeaderModele() { Key = "fieldName", Name = CommonText("thcnname"), Width = 220, Align = "left" });
            Headers.Add(new TableListHeaderModele() { Key = "fieldENName", Name = CommonText("thenname"), Width = 220, Align = "left" });
            Headers.Add(new TableListHeaderModele() { Key = "dic_GroupType", Name = Resources("thgrouptype"), Width = 120, Align = "center", IsTag = true, });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Records", Name = Resources("threcords"), Width = 120, Align = "center", IsTag = true });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Enable", Name = CommonText("thstate"), IsTag = true, Width = 100, Align = "center", SorTable = SortType.custom.ToString() });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creator", Name = CommonText("diccreator"), Width = 120, Align = "center" });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creatdate", Name = CommonText("diccreatdate"), Width = 160, Align = "center" });
            long Total = 0;
            List<PageForm_TableInfoTable> Data = business.Pages(queryModel, out Total);
            List<PageForm_TableInfoTable> res = Data.Join(tableInfos, a => a.TableCode.ToLower(), b => b.TableCode.ToLower(), (a, b) =>
            {
                a.GroupType = b.GroupType;
                a.Records = b.Records;
                a.CNName = b.CNName;
                a.ENName = b.ENName;
                return a;
            }).ToList();

            if (res.Any())
            {
                res.ForEach(o =>
                {
                    o.Dic_Records = o.Records.Value ? CommonText("globalyes") : CommonText("globalno");
                    o.Dic_GroupType = this.CommonText($"dictionary{(DictionaryType)o.GroupType}");
                    o.Dic_Enable = CommonText(o.Enable ? GlobalConst.RESOURCES_CONTENT_ENABLE_KEY : GlobalConst.RESOURCES_CONTENT_DISABLE_KEY);
                    o.Dic_Creator = EmpDictionary.ContainsKey(o.Creator) ? EmpDictionary[o.Creator] : "";
                    o.Dic_Creatdate = o.Creatdate.Value.ToString(GlobalConst.DATE_FORMAT_SECONDS);
                    o.Row_Style = o.Enable ? "" : "danger";
                    SwitchFieldKey(o);
                    o.Operations = new List<SystemButton>();
                    if (Global.IsAdmin && (Buttons is null || !Buttons.Any()))
                    {
                        BuliderButtons(o.Operations, o.TableCode, o.AutoId, ButtomType.edit);
                        BuliderButtons(o.Operations, o.TableCode, o.AutoId, ButtomType.detaile);
                        BuliderButtons(o.Operations, o.TableCode, o.AutoId, !o.Enable ? ButtomType.enable : ButtomType.disable);
                        BuliderButtons(o.Operations, o.TableCode, o.AutoId, ButtomType.delete);
                    }
                    else
                    {
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.edit.ToString()))
                            BuliderButtons(o.Operations, o.TableCode, o.AutoId, ButtomType.edit);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.detaile.ToString()))
                            BuliderButtons(o.Operations, o.TableCode, o.AutoId, ButtomType.detaile);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && (o.Value == ButtomType.enable.ToString() || o.Value == ButtomType.disable.ToString())))
                            BuliderButtons(o.Operations, o.TableCode, o.AutoId, !o.Enable ? ButtomType.enable : ButtomType.disable);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.delete.ToString()))
                            BuliderButtons(o.Operations, o.TableCode, o.AutoId, ButtomType.delete);
                    }
                });
            }
            tableListModel.Body = res;
            tableListModel.Total = Total;
            tableListModel.Header = Headers;
            if (Global.IsAdmin && (Buttons is null || !Buttons.Any()))
            {
                BuliderButtons(tableListModel.Operations, "", 0, ButtomType.add);
            }
            else
            {
                if (Buttons.Any(o => o.Value == ButtomType.add.ToString()))
                    BuliderButtons(tableListModel.Operations, "", 0, ButtomType.add);
            }
            return tableListModel.Succeed();
        }

        /// <summary>
        /// 获取单个信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public override IResponseMessage FirstOrDefault(long id)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            Form_TableInfo form_Table = business.Get<Form_TableInfo>(id);
            if (form_Table is null) return new Form_TableInfo_OutPut().Succeed();
            Form_TableInfo_OutPut _OutPut;
            ToViewModel(form_Table, out _OutPut);
            List<TableInfo> tableInfos = business.GetAll<TableInfo>();
            if (_OutPut != null)
            {
                _OutPut.Special = _OutPut.TableCode.ToLower() != "employee" && _OutPut.TableCode.ToLower() != "position" && _OutPut.TableCode.ToLower() != "organization" ? "special" : _OutPut.TableCode.ToLower();
                _OutPut.PkTable = _OutPut.TableCode;
                if (!string.IsNullOrEmpty(_OutPut.TableCode))
                {
                    TableInfo tableInfo = tableInfos.FirstOrDefault(o => o.TableCode.ToLower() == _OutPut.TableCode.ToLower());
                    if (tableInfo != null) _OutPut.Tables.Add(new Form_SametableInfo_OutPut() { TableCode = tableInfo.TableCode, TableName = Global.IsChinese ? tableInfo.CNName : tableInfo.ENName });
                }
                List<Form_Child_TableInfo_OutPut> child_TableInfo_OutPuts = business.GetForm_Child_TableInfo_OutPuts(form_Table.AutoId);
                var childs = child_TableInfo_OutPuts.Join(tableInfos, a => a.TableCode.ToLower(), b => b.TableCode.ToLower(), (a, b) =>
                {
                    a.TableName = Global.IsChinese ? b.CNName : b.ENName;
                    a.ForeignKeyName = Global.IsChinese ? "外键字段" : "A foreign key field";
                    return a;
                }).ToList();
                _OutPut.ChildTables = childs;
            }
            return _OutPut.Succeed();
        }
        public override IResponseMessage Add(Form_TableInfo_InPut data)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA));
            var ForeignKeyOpt = FlowTableFieldKey.Instance.GetForeignKey(data.TableCode);
            data.ForeignKey = ForeignKeyOpt == null ? "autoid" : $"{ForeignKeyOpt.Value}";
            Form_TableInfo resouces = new Form_TableInfo()
            {
                Enable = true,
                HaveDelete = false,
                TableCode = data.TableCode,
                ForeignKey = data.ForeignKey,
                Creatdate = DateTime.Now,
                Creator = Global.EmpId,
                Modifdate = DateTime.Now,
                Modifier = Global.EmpId,
                FlowTableCode = data.FlowTableCode,

            };
            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = IsolationLevel.ReadCommitted }))
            {
                bool b = false;
                long id = business.UnRepeatAdd(resouces);
                if (id > 0)
                {
                    List<Entity.Model.Form_Child_TableInfo> res = new List<Entity.Model.Form_Child_TableInfo>();
                    double seq = 0.1;
                    foreach (var item in data.ChildTables)
                    {
                        res.Add(new Entity.Model.Form_Child_TableInfo()
                        {
                            TableCode = item.TableCode,
                            PrimaryTableId = id,
                            Creatdate = DateTime.Now,
                            Creator = Global.EmpId,
                            Enable = true,
                            ForeignKey = "foreignkey",
                            Sequence = seq,
                            Modifdate = DateTime.Now,
                            Modifier = Global.EmpId,
                            FlowTableCode = item.FlowTableCode
                        });
                        seq = seq + 0.1;
                    }
                    b = business.Add(res, id);
                }
                else
                    return GlobalErrorType.GLOBAL_REPEAT_CODE.Failure(this.CommonText(GlobalErrorType.GLOBAL_REPEAT_CODE));
                if (b)
                {
                    ts.Complete();
                    return "".OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_SUCCESSINFO.ToString()));
                }
                else return GlobalErrorType.GLOBAL_SAVE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_FAILURE));
            }
        }

        public override IResponseMessage Edit(Form_TableInfo_InPut data)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA));
            var singe = business.Get<Form_TableInfo>(data.AutoId);
            if (singe is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            singe.Modifier = Global.EmpId;
            singe.Modifdate = DateTime.Now;
            singe.FlowTableCode = singe.FlowTableCode;
            using (TransactionScope ts = new TransactionScope())
            {
                bool b = business.Update<Form_TableInfo>(singe);
                if (b)
                {
                    List<Entity.Model.Form_Child_TableInfo> res = new List<Entity.Model.Form_Child_TableInfo>();
                    double seq = 0.1;
                    foreach (var item in data.ChildTables)
                    {
                        res.Add(new Entity.Model.Form_Child_TableInfo()
                        {
                            TableCode = item.TableCode,
                            PrimaryTableId = data.AutoId,
                            Creatdate = DateTime.Now,
                            Creator = Global.EmpId,
                            Enable = true,
                            ForeignKey = "foreignkey",
                            Sequence = seq,
                            Modifdate = DateTime.Now,
                            Modifier = Global.EmpId,
                            FlowTableCode = item.FlowTableCode
                        });
                        seq = seq + 0.1;
                    }
                    b = business.Add(res, singe.AutoId);
                }
                if (b)
                {
                    ts.Complete();
                    return "".OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_SUCCESSINFO.ToString()));
                }
                else return GlobalErrorType.GLOBAL_SAVE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_FAILURE));
            }
        }

        public override IResponseMessage Delete(long AutoID)
        {

            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            var data = business.Get<Form_TableInfo>(AutoID);
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            data.Enable = false;
            data.HaveDelete = true;
            data.Modifier = Global.EmpId;
            data.Modifdate = DateTime.Now;
            bool b = business.Update<Form_TableInfo>(data);
            if (b)
                return "".OnSucceed(this.Resources(GlobalErrorType.GLOBAL_DELETE_SUCCESSINFO));
            else return GlobalErrorType.GLOBAL_DELETE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_DELETE_FAILURE));
        }

        public override IResponseMessage Enable(long AutoID)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            var data = business.Get<Form_TableInfo>(AutoID);
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            data.Enable = !data.Enable;
            data.Modifier = Global.EmpId;
            data.Modifdate = DateTime.Now;
            bool b = business.Update<Form_TableInfo>(data);
            if (b)
                return "".OnSucceed(this.CommonText(data.Enable ? GlobalErrorType.GLOBAL_ENABLE_SUCCESSINFO : GlobalErrorType.GLOBAL_DISABLE_SUCCESSINFO));
            else return data.Enable ? GlobalErrorType.GLOBAL_ENABLE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_ENABLE_FAILURE)) : GlobalErrorType.GLOBAL_DISABLE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_DISABLE_FAILURE));

        }

        /// <summary>
        /// 获取子表数据
        /// </summary>
        /// <param name="queryModel"></param>
        /// <returns></returns>
        public override IResponseMessage Childs(QueryModel queryModel)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            ///获取基础数据库中表信息
            List<TableInfo> tableInfos = business.GetAll<TableInfo>();
            TableListModel<PageForm_TableInfoTable> tableListModel = new TableListModel<PageForm_TableInfoTable>();
            List<TableListHeaderModele> Headers = new List<TableListHeaderModele>();
            Headers.Add(new TableListHeaderModele() { Key = "rowNo", Name = CommonText("rowNo"), Width = 50, Align = "center", Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "autoId", Name = CommonText("autoid"), Width = 70, Hide = true, Align = "center", SorTable = SortType.custom.ToString(), Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "tableCode", Name = CommonText("thcode"), Width = 160, Align = "left", SorTable = SortType.custom.ToString(), Type = "primary_key", Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "cnName", Name = CommonText("thcnname"), Width = 220, Align = "left", IsOperation = true, Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "enName", Name = CommonText("thenname"), Width = 220, Align = "left", Fixed = true });
            Headers.Add(new TableListHeaderModele() { Key = "foreignKey", Name = CommonText("fieldcode"), Width = 160, Align = "left", SorTable = SortType.custom.ToString() });
            Headers.Add(new TableListHeaderModele() { Key = "fieldName", Name = CommonText("thcnname"), Width = 220, Align = "left" });
            Headers.Add(new TableListHeaderModele() { Key = "fieldENName", Name = CommonText("thenname"), Width = 220, Align = "left" });
            Headers.Add(new TableListHeaderModele() { Key = "dic_GroupType", Name = Resources("thgrouptype"), Width = 120, Align = "center", IsTag = true, });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Records", Name = Resources("threcords"), Width = 120, Align = "center", IsTag = true });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Enable", Name = CommonText("thstate"), IsTag = true, Width = 100, Align = "center", SorTable = SortType.custom.ToString() });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creator", Name = CommonText("diccreator"), Width = 120, Align = "center" });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creatdate", Name = CommonText("diccreatdate"), Width = 160, Align = "center" });
            long Total = 0;
            List<PageForm_TableInfoTable> Data = business.Childs(queryModel, out Total);
            List<PageForm_TableInfoTable> res = Data.Join(tableInfos, a => a.TableCode.ToLower(), b => b.TableCode.ToLower(), (a, b) =>
            {
                a.GroupType = b.GroupType;
                a.Records = b.Records;
                a.CNName = b.CNName;
                a.ENName = b.ENName;
                return a;
            }).ToList();

            if (res.Any())
            {
                res.ForEach(o =>
                {
                    o.Dic_Records = o.Records.Value ? CommonText("globalyes") : CommonText("globalno");
                    o.Dic_GroupType = this.CommonText($"dictionary{(DictionaryType)o.GroupType}");
                    o.Dic_Enable = CommonText(o.Enable ? GlobalConst.RESOURCES_CONTENT_ENABLE_KEY : GlobalConst.RESOURCES_CONTENT_DISABLE_KEY);
                    o.Dic_Creator = EmpDictionary.ContainsKey(o.Creator) ? EmpDictionary[o.Creator] : "";
                    o.Dic_Creatdate = o.Creatdate.Value.ToString(GlobalConst.DATE_FORMAT_SECONDS);
                    o.Row_Style = o.Enable ? "" : "danger";
                    o.Operations = new List<SystemButton>();
                    SwitchFieldKey(o);
                });
            }
            tableListModel.Body = res;
            tableListModel.Total = Total;
            tableListModel.Header = Headers;
            tableListModel.Operations = new List<SystemButton>();
            return tableListModel.Succeed();
        }
        #endregion


    

    }
}
